﻿using System;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;

namespace K9Nano.Storage.Local.Internal
{
    internal class LocalFileStorage : IFileStorage
    {
        private readonly LocalFileStorageOptions _options;
        private readonly long _maxLength;

        public LocalFileStorage(IOptionsMonitor<LocalFileStorageOptions> optionsMonitor)
        {
            _options = optionsMonitor.CurrentValue;

            if (!Directory.Exists(_options.Path))
            {
                Directory.CreateDirectory(_options.Path);
            }

            _maxLength = _options.GetLength();
        }

        public string Save(Stream stream, string ext)
        {
            if(stream.Length > _maxLength) throw new IOException("文件大小超过限制");
            var file = CreateUniqueFilePath(ext);
            var write = ((IFileStorage)this).OpenWrite(file);
            stream.CopyTo(write);
            return file;
        }

        public async ValueTask<string> SaveAsync(Stream stream, string ext, CancellationToken cancellation)
        {
            if (stream.Length > _maxLength) throw new IOException("文件大小超过限制");
            var file = CreateUniqueFilePath(ext);
            var write = ((IFileStorage)this).OpenWrite(file);
            await stream.CopyToAsync(write, cancellation);
            return file;
        }

        private string GetUniquePath()
        {
            var today = DateTimeOffset.Now;
            var path = Path.Combine(_options.Path, today.Year.ToString(), today.Month.ToString(), today.Day.ToString());
            Directory.CreateDirectory(path);
            return path;
        }

        private string CreateUniqueFilePath(string ext)
        {
            var path = GetUniquePath();
            var file = Path.Combine(path, Guid.NewGuid() + ext);
            return file;
        }
    }
}